/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id$
 */
package wx.xml.xalan.xalan.templates;

import wx.xml.xalan.xml.utils.QName;
import wx.xml.xalan.xpath.XPath;

/**
 * Holds the attribute declarations for the xsl:keys element.
 * A stylesheet declares a set of keys for each document using
 * the xsl:key element. When this set of keys contains a member
 * with node x, name y and value z, we say that node x has a key
 * with name y and value z.
 *
 * @xsl.usage internal
 * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
 */
public class KeyDeclaration extends ElemTemplateElement {
    static final long serialVersionUID = 7724030248631137918L;
    /**
     * The "name" property.
     *
     * @serial
     */
    private QName m_name;
    /**
     * The "match" attribute.
     *
     * @serial
     */
    private XPath m_matchPattern = null;
    /**
     * The "use" attribute.
     *
     * @serial
     */
    private XPath m_use;

    /**
     * Constructs a new element representing the xsl:key.  The parameters
     * are needed to prioritize this key element as part of the recomposing
     * process.  For this element, they are not automatically created
     * because the element is never added on to the stylesheet parent.
     */
    public KeyDeclaration(Stylesheet parentNode, int docOrderNumber) {
        m_parentNode = parentNode;
        setUid(docOrderNumber);
    }

    /**
     * Get the "name" attribute.
     * The name attribute specifies the name of the key. The value
     * of the name attribute is a QName, which is expanded as
     * described in [2.4 Qualified Names].
     *
     * @return Value of the "name" attribute.
     */
    public QName getName() {
        return m_name;
    }

    /**
     * Set the "name" attribute.
     * The name attribute specifies the name of the key. The value
     * of the name attribute is a QName, which is expanded as
     * described in [2.4 Qualified Names].
     *
     * @param name Value to set for the "name" attribute.
     */
    public void setName(QName name) {
        m_name = name;
    }

    /**
     * Return the node name.
     *
     * @return the element's name
     */
    public String getNodeName() {
        return Constants.ELEMNAME_KEY_STRING;
    }

    /**
     * Get the "match" attribute.
     * The match attribute is a Pattern; an xsl:key element gives
     * information about the keys of any node that matches the
     * pattern specified in the match attribute.
     *
     * @return Value of the "match" attribute.
     * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
     */
    public XPath getMatch() {
        return m_matchPattern;
    }

    /**
     * Set the "match" attribute.
     * The match attribute is a Pattern; an xsl:key element gives
     * information about the keys of any node that matches the
     * pattern specified in the match attribute.
     *
     * @param v Value to set for the "match" attribute.
     * @see <a href="http://www.w3.org/TR/xslt#patterns">patterns in XSLT Specification</a>
     */
    public void setMatch(XPath v) {
        m_matchPattern = v;
    }

    /**
     * Get the "use" attribute.
     * The use attribute is an expression specifying the values
     * of the key; the expression is evaluated once for each node
     * that matches the pattern.
     *
     * @return Value of the "use" attribute.
     */
    public XPath getUse() {
        return m_use;
    }

    /**
     * Set the "use" attribute.
     * The use attribute is an expression specifying the values
     * of the key; the expression is evaluated once for each node
     * that matches the pattern.
     *
     * @param v Value to set for the "use" attribute.
     */
    public void setUse(XPath v) {
        m_use = v;
    }

    /**
     * Get an int constant identifying the type of element.
     *
     * @return The token ID for this element
     * @see wx.xml.xalan.xalan.templates.Constants
     */
    public int getXSLToken() {
        return Constants.ELEMNAME_KEY;
    }

    /**
     * This function is called after everything else has been
     * recomposed, and allows the template to set remaining
     * values that may be based on some other property that
     * depends on recomposition.
     */
    public void compose(StylesheetRoot sroot)
        throws javax.xml.transform.TransformerException {
        super.compose(sroot);
        java.util.Vector vnames = sroot.getComposeState().getVariableNames();
        if (null != m_matchPattern)
            m_matchPattern.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
        if (null != m_use)
            m_use.fixupVariables(vnames, sroot.getComposeState().getGlobalsSize());
    }

    /**
     * This function is called during recomposition to
     * control how this element is composed.
     *
     * @param root The root stylesheet for this transformation.
     */
    public void recompose(StylesheetRoot root) {
        root.recomposeKeys(this);
    }

}
